home *** CD-ROM | disk | FTP | other *** search
/ AMIGA-CD 2 / Amiga-CD - Volume 2.iso / neue_programme / util / arc / unrar / unpack.c < prev    next >
C/C++ Source or Header  |  1995-06-01  |  16KB  |  755 lines

  1. /******    *****   ******
  2.  **   **  **   **  **   **      unRAR utility version 1.00e
  3.  ******   *******  ******       ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4.  **   **  **   **  **   **         FREE portable version
  5.  **   **  **   **  **   **         ~~~~~~~~~~~~~~~~~~~~~
  6.  
  7.      Unpacking algorithm procedures
  8.  
  9.    YOU DO NOT NEED CHANGING THERE ANYTHING.
  10. */
  11.  
  12. #include "unrar.h"
  13.  
  14. void MakeTbl(void);               /* Makes Huffman table */
  15. void AddBit(unsigned int);                /* Shift buffer pointer to NBits */
  16. void CopyString(UWORD,unsigned int);            /* string copy */
  17. void ShortLZ(void);               /* unpacks short, near and special LZ codes */
  18. void LongLZ(void);                /* unpacks long and far LZ codes */
  19. void HuffDecode(void);            /* Huffman decoding */
  20. int  UnpWriteBuf(void);           /* writes output buffer */
  21. int  UnpReadBuf(int);            /* reads output buffer */
  22. void GetFlagsBuf(void);           /* gets flag byte */
  23. void UnpInitData(int);           /* reset initial data */
  24. void InitHuff(void);              /* initializing Huffman tables */
  25. void CorrHuff(UWORD *, UBYTE *);              /* Huffman table correction in case of overflow */
  26. void CreateEncTbl(HPBYTE);          /* create decoding tables */
  27. void CreateOneTbl(UWORD *,UBYTE *,UBYTE *,UBYTE);          /* subfunction of previous */
  28. int  unpack();                /* unpacking procedure itself */
  29.  
  30. #define     SUSPEND     1
  31. #define     SIZE_PBUF   0x2000
  32. #define     FIRST       1
  33. #define     NEXT        2
  34. #define     UNP_MEMORY  0x10010L+sizeof(struct UnpData)+ \
  35.                         sizeof(struct DecodeTables)+SIZE_PBUF
  36.  
  37.  
  38. UWORD hcdsh1[]={ 0x0001,0xa003,0xd004,0xe004,0xf005,0xf806,0xfc07,0xfe08,
  39.                  0xff08,0xc004,0x8004,0x9005,0x9806,0x9c06,0 };
  40.  
  41. UWORD hcdsh2[]={ 0x0002,0x4003,0x6003,0xa003,0xd004,0xe004,0xf005,0xf806,
  42.                  0xfc06,0xc004,0x8004,0x9005,0x9806,0x9c06,0 };
  43.  
  44. UWORD hcdsh3[]={ 0x0001,0xa004,0xd004,0xe004,0xf005,0xf806,0xfc07,0xfe08,
  45.                  0xff08,0xc004,0x8004,0x9005,0x9806,0x9c06,0xb004,0 };
  46.  
  47. UWORD hcdsh4[]={ 0x0002,0x4003,0x6003,0xa004,0xd004,0xe004,0xf005,0xf806,
  48.                  0xfc06,0xc004,0x8004,0x9005,0x9806,0x9c06,0xb004,0 };
  49.  
  50. UWORD hcdln0[]={ 0x8001,0x4002,0x2003,0x1004,0x0805,0x0406,0x0207,0x0108,
  51.                  0x0008,0 };
  52.  
  53. UWORD hcdln1[258],hcdln2[258];
  54. UWORD hcode0[258],hcode1[258],hcode2[258],hcode3[258],hcode4[258];
  55.  
  56. struct MakeHuffTabs
  57. {
  58.   UWORD *Table;
  59.   UBYTE HuffCodeCount[12];
  60. } MakeTab[]={
  61.  {hcdln1,{0  ,2  ,1  ,2  ,2  ,4   ,5   ,4   ,4   ,8   ,0   ,224}},
  62.  {hcdln2,{0  ,0  ,5  ,2  ,2  ,4   ,5   ,4   ,4   ,8   ,2   ,220}},
  63.  {hcode0,{0  ,0  ,0  ,8  ,8  ,8   ,9   ,0   ,0   ,0   ,0   ,224}},
  64.  {hcode1,{0  ,0  ,0  ,0  ,4  ,40  ,16  ,16  ,4   ,0   ,47  ,130}},
  65.  {hcode2,{0  ,0  ,0  ,0  ,2  ,5   ,46  ,64  ,116 ,24  ,0   ,0  }},
  66.  {hcode3,{0  ,0  ,0  ,0  ,0  ,2   ,14  ,202 ,33  ,6   ,0   ,0  }},
  67.  {hcode4,{0  ,0  ,0  ,0  ,0  ,0   ,0   ,255 ,2   ,0   ,0   ,0  }}};
  68.  
  69.  
  70. SDWORD DestUnpSize=0;
  71. UBYTE  FlagBuf;
  72. UWORD  InAdr,OutAdr;
  73.  
  74. unsigned int Suspend=0;
  75. unsigned int NumBit;
  76. unsigned int LCount;
  77. int FlagsCnt;
  78.  
  79. struct UnpData
  80. {
  81.   UWORD ChSet[256];
  82.   UBYTE Place[256];
  83.   UBYTE NToPl[256];
  84.  
  85.   UBYTE ChSetA[256];
  86.   UBYTE PlaceA[256];
  87.  
  88.   UWORD ChSetB[256];
  89.   UBYTE PlaceB[256];
  90.   UBYTE NToPlB[256];
  91.  
  92.   UWORD ChSetC[256];
  93.   UBYTE PlaceC[256];
  94.   UBYTE NToPlC[256];
  95.  
  96.   UWORD AvrPlc;
  97.   UWORD AvrPlcB;
  98.   UWORD AvrLn1;
  99.   UWORD AvrLn2;
  100.   UWORD AvrLn3;
  101.  
  102.   UBYTE NumHuf;
  103.   UBYTE StMode;
  104.  
  105.   UWORD Nhfb;
  106.   UWORD Nlzb;
  107.  
  108.   UWORD MaxDist3;
  109.   UBYTE Buf60;
  110.   UWORD WrAddr;
  111.   UWORD SomeRd;
  112.   UWORD UnpAllBuf;
  113.  
  114.   UWORD LastDist;
  115.   UWORD LastLen;
  116.   UWORD OldDist[4];
  117.   UWORD OldDistNum;
  118. } *D;
  119.  
  120.  
  121. struct DecodeTables
  122. {
  123.   UBYTE ECDSH1[256];
  124.   UBYTE ECDSH2[256];
  125.   UBYTE ECDSH3[256];
  126.   UBYTE ECDSH4[256];
  127.  
  128.   UBYTE ECDLN0[256];
  129.   UBYTE ECDLN1[4096];
  130.   UBYTE ECDLN2[4096];
  131.   UBYTE ECODE0[4096];
  132.   UBYTE ECODE1[4096];
  133.   UBYTE ECODE2[1024];
  134.   UBYTE ECODE3[1024];
  135.   UBYTE ECODE4[1024];
  136.   UBYTE NCDSH1[16];
  137.   UBYTE NCDSH2[16];
  138.   UBYTE NCDSH3[16];
  139.   UBYTE NCDSH4[16];
  140.   UBYTE NCDLN0[256];
  141.   UBYTE NCDLN1[256];
  142.   UBYTE NCDLN2[256];
  143.   UBYTE NCODE0[257];
  144.   UBYTE NCODE1[257];
  145.   UBYTE NCODE2[257];
  146.   UBYTE NCODE3[257];
  147.   UBYTE NCODE4[257];
  148. } *T;
  149.  
  150. UBYTE *PackBuf;
  151. HPBYTE UnpBuf;
  152.  
  153. int (* UnpReadFn)();
  154. int (* UnpWriteFn)();
  155.  
  156.  
  157. #define GetField() ((UWORD)((((UDWORD)PackBuf[InAdr] << 16) |         \
  158.                    ((UWORD)PackBuf[InAdr+1] << 8) | PackBuf[InAdr+2]) \
  159.                     >> (8-NumBit)))
  160.  
  161. void AddBit(NBits)
  162. unsigned int NBits;
  163. {
  164.   InAdr += (NumBit+NBits) >> 3;
  165.   NumBit = (NumBit+NBits) & 7;
  166. }
  167.  
  168. void CopyString(Distance,Length)
  169. UWORD Distance;
  170. unsigned int Length;
  171. {
  172.   DestUnpSize-=Length;
  173.   while (Length--)
  174.   {
  175.     UnpBuf[OutAdr]=UnpBuf[(UWORD)(OutAdr-Distance)];
  176.     OutAdr++;
  177.   }
  178. }
  179.  
  180. int unpack(UnpMem,UnpRead,UnpWrite,Solid)
  181. HPBYTE UnpMem;
  182. int (* UnpRead)();
  183. int (* UnpWrite)();
  184. int Solid;
  185. {
  186.   UnpReadFn=UnpRead;
  187.   UnpWriteFn=UnpWrite;
  188.   UnpBuf=(UBYTE *)UnpMem;
  189.   PackBuf=(UBYTE *)(UnpMem+0x10000L+sizeof(struct UnpData)+sizeof(struct DecodeTables));
  190.   D=(struct UnpData *)(UnpMem+0x10000L);
  191.  
  192.   if (Suspend)
  193.     OutAdr=D->WrAddr;
  194.   else
  195.   {
  196.     UnpInitData(Solid);
  197.     if (!Solid)
  198.     {
  199.       InitHuff();
  200.       memset(UnpBuf,0,0x8000);
  201.       memset(UnpBuf+0x8000,0,0x8000);
  202.       OutAdr=0;
  203.     }
  204.     else
  205.       OutAdr=D->WrAddr;
  206.     if (--DestUnpSize < 0)
  207.       return(0);
  208.  
  209.     if (UnpReadBuf(FIRST)==-1)
  210.       return(-1);
  211.  
  212.     GetFlagsBuf();
  213.     FlagsCnt=8;
  214.   }
  215.  
  216.   while (DestUnpSize>=0)
  217.   {
  218.     if (InAdr >= SIZE_PBUF-12)
  219.       if (UnpReadBuf(NEXT)==-1)
  220.         return(-1);
  221.     if ((UWORD)(D->WrAddr - OutAdr) < 0x110 && D->WrAddr!=OutAdr)
  222.     {
  223.       if (UnpWriteBuf()==-1)
  224.         return(-1);
  225.       if (Suspend)
  226.         return(0);
  227.     }
  228.  
  229.     if (D->StMode)
  230.     {
  231.       HuffDecode();
  232.       continue;
  233.     }
  234.  
  235.     if (--FlagsCnt < 0)
  236.     {
  237.       GetFlagsBuf();
  238.       FlagsCnt=7;
  239.     }
  240.  
  241.     if (FlagBuf >= 0x80)
  242.     {
  243.       FlagBuf<<=1;
  244.       if (D->Nlzb > D->Nhfb)
  245.         LongLZ();
  246.       else
  247.         HuffDecode();
  248.     }
  249.     else
  250.     {
  251.       FlagBuf<<=1;
  252.       if (--FlagsCnt < 0)
  253.       {
  254.         GetFlagsBuf();
  255.         FlagsCnt=7;
  256.       }
  257.       if (FlagBuf >= 0x80)
  258.       {
  259.         FlagBuf<<=1;
  260.         if (D->Nlzb > D->Nhfb)
  261.           HuffDecode();
  262.         else
  263.           LongLZ();
  264.       }
  265.       else
  266.       {
  267.         FlagBuf<<=1;
  268.         ShortLZ();
  269.       }
  270.     }
  271.   }
  272.   if (UnpWriteBuf()==-1)
  273.     return(-1);
  274.   return(0);
  275. }
  276.  
  277.  
  278. void ShortLZ()
  279. {
  280.   UWORD LengthCode,SaveLength;
  281.   UBYTE LastDistance;
  282.   UWORD Distance,DistancePlace,Length;
  283.   D->NumHuf=0;
  284.   LengthCode=GetField();
  285.   if (LCount==2)
  286.   {
  287.     AddBit(1);
  288.     if (LengthCode >= 0x8000)
  289.     {
  290.       CopyString(D->LastDist,D->LastLen);
  291.       return;
  292.     }
  293.     LengthCode <<= 1;
  294.     LCount=0;
  295.   }
  296.   LengthCode >>= 8;
  297.   if (D->Buf60==0)
  298.     if (D->AvrLn1<37)
  299.     {
  300.       Length=T->ECDSH1[LengthCode];
  301.       AddBit(T->NCDSH1[Length]);
  302.     }
  303.     else
  304.     {
  305.       Length=T->ECDSH2[LengthCode];
  306.       AddBit(T->NCDSH2[Length]);
  307.     }
  308.   else
  309.     if (D->AvrLn1<37)
  310.     {
  311.       Length=T->ECDSH3[LengthCode];
  312.       AddBit(T->NCDSH3[Length]);
  313.     }
  314.     else
  315.     {
  316.       Length=T->ECDSH4[LengthCode];
  317.       AddBit(T->NCDSH4[Length]);
  318.     }
  319.  
  320.   if (Length >= 9)
  321.   {
  322.     if (Length == 9)
  323.     {
  324.       LCount++;
  325.       CopyString(D->LastDist,D->LastLen);
  326.       return;
  327.     }
  328.     if (Length == 14)
  329.     {
  330.       LCount=0;
  331.       Length=T->ECDLN2[GetField() >> 4];
  332.       AddBit(T->NCDLN2[Length]);
  333.       Length+=5;
  334.       Distance=(GetField() >> 1) | 0x8000;
  335.       AddBit(15);
  336.       D->LastLen=Length;
  337.       D->LastDist=Distance;
  338.       CopyString(Distance,Length);
  339.       return;
  340.     }
  341.  
  342.     LCount=0;
  343.     SaveLength=Length;
  344.     Distance=D->OldDist[(D->OldDistNum-(Length-9)) & 3];
  345.     Length=T->ECDLN1[GetField() >> 4];
  346.     AddBit(T->NCDLN1[Length]);
  347.     Length+=2;
  348.     if (Length==0x101 && SaveLength==10)
  349.     {
  350.       D->Buf60 ^= 1;
  351.       return;
  352.     }
  353.     if (Distance > 256)
  354.       Length++;
  355.     if (Distance > D->MaxDist3)
  356.       Length++;
  357.  
  358.     D->OldDist[D->OldDistNum++]=Distance;
  359.     D->OldDistNum = D->OldDistNum & 3;
  360.     D->LastLen=Length;
  361.     D->LastDist=Distance;
  362.     CopyString(Distance,Length);
  363.     return;
  364.   }
  365.  
  366.   LCount=0;
  367.   D->AvrLn1 += Length;
  368.   D->AvrLn1 -= D->AvrLn1 >> 4;
  369.  
  370.   DistancePlace=T->ECODE2[GetField() >> 6];
  371.   AddBit(T->NCODE2[DistancePlace]);
  372.   Distance=D->ChSetA[DistancePlace];
  373.   if (--DistancePlace != 0xFFFF)
  374.   {
  375.     D->PlaceA[Distance]--;
  376.     LastDistance=D->ChSetA[DistancePlace];
  377.     D->PlaceA[LastDistance]++;
  378.     D->ChSetA[DistancePlace+1]=LastDistance;
  379.     D->ChSetA[DistancePlace]=(UBYTE)Distance;
  380.   }
  381.   Length+=2;
  382.   D->OldDist[D->OldDistNum++] = ++Distance;
  383.   D->OldDistNum = D->OldDistNum & 3;
  384.   D->LastLen=Length;
  385.   D->LastDist=Distance;
  386.   CopyString(Distance,Length);
  387.   return;
  388. }
  389.  
  390.  
  391. void LongLZ()
  392. {
  393.   UWORD LengthCode,Length;
  394.   UWORD Distance,DistancePlace,NewDistancePlace;
  395.   UWORD oldav2,oldav3;
  396.  
  397.   D->NumHuf=0;
  398.   D->Nlzb+=16;
  399.   if (D->Nlzb > 0xff)
  400.   {
  401.     D->Nlzb=0x90;
  402.     D->Nhfb >>= 1;
  403.   }
  404.   oldav2=D->AvrLn2;
  405.   if (D->AvrLn2 >= 122)
  406.   {
  407.     Length=T->ECDLN2[GetField() >> 4];
  408.     AddBit(T->NCDLN2[Length]);
  409.   }
  410.   else
  411.     if (D->AvrLn2 >= 64)
  412.     {
  413.       Length=T->ECDLN1[GetField() >> 4];
  414.       AddBit(T->NCDLN1[Length]);
  415.     }
  416.     else
  417.     {
  418.       LengthCode=GetField();
  419.       if (LengthCode < 0x100)
  420.       {
  421.         Length=LengthCode;
  422.         AddBit(16);
  423.       }
  424.       else
  425.       {
  426.         Length=T->ECDLN0[LengthCode >> 8];
  427.         AddBit(T->NCDLN0[Length]);
  428.       }
  429.     }
  430.  
  431.   D->AvrLn2 += Length;
  432.   D->AvrLn2 -= D->AvrLn2 >> 5;
  433.   if (D->AvrPlcB > 0x28ff)
  434.   {
  435.     DistancePlace=T->ECODE2[GetField() >> 6];
  436.     AddBit(T->NCODE2[DistancePlace]);
  437.   }
  438.   else
  439.     if (D->AvrPlcB > 0x6ff)
  440.     {
  441.       DistancePlace=T->ECODE1[GetField() >> 4];
  442.       AddBit(T->NCODE1[DistancePlace]);
  443.     }
  444.     else
  445.     {
  446.       DistancePlace=T->ECODE0[GetField() >> 4];
  447.       AddBit(T->NCODE0[DistancePlace]);
  448.     }
  449.  
  450.   D->AvrPlcB += DistancePlace;
  451.   D->AvrPlcB -= D->AvrPlcB >> 8;
  452.   while (1)
  453.   {
  454.     Distance = D->ChSetB[DistancePlace];
  455.     NewDistancePlace = D->NToPlB[Distance++ & 0xff]++;
  456.     if (!(Distance & 0xff))
  457.     {
  458.       Distance-=0x100;
  459.       CorrHuff(D->ChSetB,D->NToPlB);
  460.     }
  461.     else
  462.       break;
  463.   }
  464.  
  465.   D->ChSetB[DistancePlace]=D->ChSetB[NewDistancePlace];
  466.   D->ChSetB[NewDistancePlace]=Distance;
  467.  
  468.   Distance=((UWORD)((Distance & ~0xff) | (GetField() >> 8))) >> 1;
  469.   AddBit(7);
  470.  
  471.   oldav3=D->AvrLn3;
  472.   if (Length!=1 && Length!=4)
  473.     if (Length==0 && Distance <= D->MaxDist3)
  474.     {
  475.       D->AvrLn3++;
  476.       D->AvrLn3 -= D->AvrLn3 >> 8;
  477.     }
  478.     else
  479.       if (D->AvrLn3 > 0)
  480.         D->AvrLn3--;
  481.   Length+=3;
  482.   if (Distance >= D->MaxDist3)
  483.     Length++;
  484.   if (Distance <= 256)
  485.     Length+=8;
  486.   if (oldav3 > 0xb0 || D->AvrPlc >= 0x2a00 && oldav2 < 0x40)
  487.     D->MaxDist3=0x7f00;
  488.   else
  489.     D->MaxDist3=0x2001;
  490.   D->OldDist[D->OldDistNum++]=Distance;
  491.   D->OldDistNum = D->OldDistNum & 3;
  492.   D->LastLen=Length;
  493.   D->LastDist=Distance;
  494.   CopyString(Distance,Length);
  495. }
  496.  
  497.  
  498. void HuffDecode()
  499. {
  500.   UWORD CurByte,BytePlace,NewBytePlace;
  501.   UWORD Length,Distance,Code;
  502.  
  503.   Code=GetField();
  504.  
  505.   if (D->AvrPlc > 0x75ff)
  506.   {
  507.     BytePlace=T->ECODE4[Code>>6];
  508.     if (D->StMode && BytePlace==0 && Code > 0xfff)
  509.       BytePlace=0x100;
  510.     AddBit(T->NCODE4[BytePlace]);
  511.   }
  512.   else
  513.     if (D->AvrPlc > 0x5dff)
  514.     {
  515.       BytePlace=T->ECODE3[Code>>6];
  516.       if (D->StMode && BytePlace==0 && Code > 0xfff)
  517.         BytePlace=0x100;
  518.       AddBit(T->NCODE3[BytePlace]);
  519.     }
  520.     else
  521.       if (D->AvrPlc > 0x35ff)
  522.       {
  523.         BytePlace=T->ECODE2[Code>>6];
  524.         if (D->StMode && BytePlace==0 && Code > 0xfff)
  525.           BytePlace=0x100;
  526.         AddBit(T->NCODE2[BytePlace]);
  527.       }
  528.       else
  529.         if (D->AvrPlc > 0x0dff)
  530.         {
  531.           BytePlace=T->ECODE1[Code>>4];
  532.           if (D->StMode && BytePlace==0 && Code > 0xfff)
  533.             BytePlace=0x100;
  534.           AddBit(T->NCODE1[BytePlace]);
  535.         }
  536.         else
  537.         {
  538.           BytePlace=T->ECODE0[Code>>4];
  539.           if (D->StMode && BytePlace==0 && Code > 0xfff)
  540.             BytePlace=0x100;
  541.           AddBit(T->NCODE0[BytePlace]);
  542.         }
  543.   if (D->StMode)
  544.   {
  545.     if (--BytePlace==0xFFFF)
  546.     {
  547.       Code=GetField();
  548.       AddBit(1);
  549.       if (Code >= 0x8000)
  550.       {
  551.         D->NumHuf=D->StMode=0;
  552.         return;
  553.       }
  554.       else
  555.       {
  556.         Length = (Code & 0x4000) ? 4 : 3;
  557.         Distance= T->ECODE2[(Code >> 4) & 0x3ff];
  558.         AddBit(T->NCODE2[Distance]+1);
  559.         Distance = (Distance << 5) | (GetField() >> 11);
  560.         AddBit(5);
  561.         CopyString(Distance,Length);
  562.         return;
  563.       }
  564.     }
  565.   }
  566.   else
  567.     if (D->NumHuf++ >= 16 && FlagsCnt==0)
  568.       D->StMode=1;
  569.   D->AvrPlc += BytePlace;
  570.   D->AvrPlc -= D->AvrPlc >> 8;
  571.   D->Nhfb+=16;
  572.   if (D->Nhfb > 0xff)
  573.   {
  574.     D->Nhfb=0x90;
  575.     D->Nlzb >>= 1;
  576.   }
  577.  
  578.   UnpBuf[OutAdr++]=(UBYTE)(D->ChSet[BytePlace]>>8);
  579.   DestUnpSize--;
  580.  
  581.   while (1)
  582.   {
  583.     CurByte=D->ChSet[BytePlace];
  584.     NewBytePlace=D->NToPl[CurByte++ & 0xff]++;
  585.     if ((CurByte & 0xff) > 0xa1)
  586.       CorrHuff(D->ChSet,D->NToPl);
  587.     else
  588.       break;
  589.   }
  590.  
  591.   D->ChSet[BytePlace]=D->ChSet[NewBytePlace];
  592.   D->ChSet[NewBytePlace]=CurByte;
  593. }
  594.  
  595.  
  596. int UnpWriteBuf()
  597. {
  598.   if (OutAdr<D->WrAddr)
  599.   {
  600.     if (UnpWriteFn((UBYTE *)(UnpBuf+D->WrAddr),(UWORD)-D->WrAddr)==-1 ||
  601.         UnpWriteFn((UBYTE *)UnpBuf,(UWORD)OutAdr)==-1)
  602.       return(-1);
  603.   }
  604.   else
  605.     if (UnpWriteFn((UBYTE *)(UnpBuf+D->WrAddr),(UWORD)(OutAdr-D->WrAddr))==-1)
  606.       return(-1);
  607.   D->WrAddr=OutAdr;
  608.   return(0);
  609. }
  610.  
  611.  
  612. int UnpReadBuf(NumBuf)
  613. int NumBuf;
  614. {
  615.   int ReadCode;
  616.   if (NumBuf==FIRST)
  617.     ReadCode=UnpReadFn(PackBuf,SIZE_PBUF);
  618.   else
  619.   {
  620.     memcpy(PackBuf,PackBuf+InAdr,(UWORD)(SIZE_PBUF-InAdr));
  621.     ReadCode=UnpReadFn(PackBuf+SIZE_PBUF-InAdr,(UWORD)InAdr);
  622.   }
  623.   InAdr=0;
  624.   if (ReadCode==-1)
  625.     return(-1);
  626.   return(0);
  627. }
  628.  
  629. void GetFlagsBuf()
  630. {
  631.   UWORD Flags,FlagsPlace,NewFlagsPlace;
  632.  
  633.   FlagsPlace=T->ECODE2[GetField() >> 6];
  634.   AddBit(T->NCODE2[FlagsPlace]);
  635.  
  636.   while (1)
  637.   {
  638.     Flags=D->ChSetC[FlagsPlace];
  639.     FlagBuf=(UBYTE)(Flags >> 8);
  640.     NewFlagsPlace=D->NToPlC[Flags++ & 0xff]++;
  641.     if ((Flags & 0xff) == 0)
  642.     {
  643.       Flags-=0x100;
  644.       CorrHuff(D->ChSetC,D->NToPlC);
  645.     }
  646.     else
  647.       break;
  648.   }
  649.  
  650.   D->ChSetC[FlagsPlace]=D->ChSetC[NewFlagsPlace];
  651.   D->ChSetC[NewFlagsPlace]=Flags;
  652. }
  653.  
  654.  
  655. void UnpInitData(Solid)
  656. int Solid;
  657. {
  658.   if (!Solid)
  659.   {
  660.     memset(D,0,sizeof(struct UnpData));
  661.     D->AvrPlc=0x3500;
  662.     D->MaxDist3=0x2001;
  663.     D->Nhfb=D->Nlzb=0x80;
  664.   }
  665.   FlagsCnt=0;
  666.   FlagBuf=0;
  667.   InAdr=0;
  668.   NumBit=0;
  669.   D->StMode=0;
  670.   LCount=0;
  671. }
  672.  
  673. void InitHuff()
  674. {
  675.   UWORD I;
  676.   for (I=0;I<256;I++)
  677.   {
  678.     D->Place[I]=D->PlaceA[I]=D->PlaceB[I]=(UBYTE)I;
  679.     D->PlaceC[I]=(UBYTE)(~I+1);
  680.     D->ChSet[I]=D->ChSetB[I]=I<<8;
  681.     D->ChSetA[I]=(UBYTE)I;
  682.     D->ChSetC[I]=(~I+1)<<8;
  683.   }
  684.   memset(D->NToPl,0,sizeof(D->NToPl));
  685.   memset(D->NToPlB,0,sizeof(D->NToPlB));
  686.   memset(D->NToPlC,0,sizeof(D->NToPlC));
  687.   CorrHuff(D->ChSetB,D->NToPlB);
  688. }
  689.  
  690.  
  691. void CorrHuff(CharSet,NumToPlace)
  692. UWORD *CharSet;
  693. UBYTE *NumToPlace;
  694. {
  695.   int I,J;
  696.   for (I=7;I>=0;I--)
  697.     for (J=0;J<32;J++,CharSet++)
  698.       *CharSet=(*CharSet & ~0xff) | I;
  699.   memset(NumToPlace,0,sizeof(D->NToPl));
  700.   for (I=6;I>=0;I--)
  701.     NumToPlace[I]=(7-I)*32;
  702. }
  703.  
  704. void CreateEncTbl(UnpMem)
  705. HPBYTE UnpMem;
  706. {
  707.   T=(struct DecodeTables *)(UnpMem+0x10000L+sizeof(struct UnpData));
  708.   CreateOneTbl(hcdsh1,T->ECDSH1,T->NCDSH1,8);
  709.   CreateOneTbl(hcdsh2,T->ECDSH2,T->NCDSH2,8);
  710.   CreateOneTbl(hcdsh3,T->ECDSH3,T->NCDSH3,8);
  711.   CreateOneTbl(hcdsh4,T->ECDSH4,T->NCDSH4,8);
  712.   CreateOneTbl(hcdln0,T->ECDLN0,T->NCDLN0,8);
  713.   CreateOneTbl(hcdln1,T->ECDLN1,T->NCDLN1,4);
  714.   CreateOneTbl(hcdln2,T->ECDLN2,T->NCDLN2,4);
  715.   CreateOneTbl(hcode0,T->ECODE0,T->NCODE0,4);
  716.   CreateOneTbl(hcode1,T->ECODE1,T->NCODE1,4);
  717.   CreateOneTbl(hcode2,T->ECODE2,T->NCODE2,6);
  718.   CreateOneTbl(hcode3,T->ECODE3,T->NCODE3,6);
  719.   CreateOneTbl(hcode4,T->ECODE4,T->NCODE4,6);
  720. }
  721.  
  722.  
  723. void CreateOneTbl(hcd,ecd,ncd,ShiftCount)
  724. UWORD *hcd;
  725. UBYTE *ecd;
  726. UBYTE *ncd;
  727. UBYTE ShiftCount;
  728. {
  729.   UWORD I,MaxCode,Code;
  730.   for (I=0; hcd[I]; I++)
  731.   {
  732.     ncd[I]=(UBYTE)(hcd[I] & 0xf);
  733.     Code=hcd[I] >> ShiftCount;
  734.     MaxCode=1 << (16-ShiftCount-(UBYTE)(hcd[I] & 0xf));
  735.     while (MaxCode--)
  736.       ecd[Code++]=(UBYTE)I;
  737.   }
  738. }
  739.  
  740.  
  741. void MakeTbl()
  742. {
  743.   UWORD I,J,K,Code;
  744.   UWORD *OutTab;
  745.   for (I=0;I<sizeof(MakeTab)/sizeof(MakeTab[0]);I++)
  746.   {
  747.     OutTab=MakeTab[I].Table;
  748.     for (Code=J=0;J<12;J++)
  749.       for (Code<<=1,K=0;K<MakeTab[I].HuffCodeCount[J];K++)
  750.         *(OutTab++)=(Code++ << (4+11-J)) | (J + 1);
  751.     *OutTab=0;
  752.   }
  753. }
  754.  
  755.